package com.cole.miniapp.project.controller;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import com.cole.miniapp.common.annotation.LoginUser;
import com.cole.miniapp.common.bean.ResponseResult;
import com.cole.miniapp.common.service.RedisHashService; 
import com.cole.miniapp.project.domain.*;
import com.cole.miniapp.project.domain.vo.FcmStoreVO;
import com.cole.miniapp.project.mapper.FcmUserMapper;
import com.cole.miniapp.project.service.PayService;
import com.cole.miniapp.project.service.StoreService;
import com.cole.miniapp.project.service.UserService; 
import com.cole.miniapp.project.vo.SessionInfoEntity;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/api/user")
public class UserController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private WxMaService wxMaService;

    @Autowired
    private UserService userService;

    @Autowired
    private StoreService storeService;

    @Autowired
    private PayService payService;

    @Autowired
   	@Qualifier("redisSessionServiceByHash")
   	RedisHashService<String, SessionInfoEntity> sessionService;

    /**
     * 登陆接口
     * @param fcmUser
     * @param code
     * @return
     */
    @PostMapping(value = "/login")
    public ResponseResult login( @LoginUser(required = false) FcmUser fcmUser,String code) {
        ResponseResult result = ResponseResult.success();
        if (StringUtils.isBlank(code)) {
            result = ResponseResult.error();
            result.setMsg("empty jscode");
            return result;
        }
        try {
            if (fcmUser!=null){
                SessionInfoEntity sessionInfoEntity = sessionService.get(fcmUser.getId().toString());
                result.setData(fcmUser);
                result.setMsg(sessionInfoEntity.getLoginToken());
                return result;
            }
            //传入code获取openid、sessionkey和unionid;
            WxMaJscode2SessionResult wxMaJscode2SessionResult = wxMaService.getUserService().getSessionInfo(code);

            //处理用户，判断是否为新用户，是：返回用户信息，否：插入用户信息后返回用户信息
            fcmUser = userService.userLogin(wxMaJscode2SessionResult);
            //将微信的sessionkey和我生成的accesstoken存到redis服务器中 
            String accessToken = UUID.randomUUID().toString().replace("-", "");
            SessionInfoEntity sessionInfoEntity =new SessionInfoEntity();
            Date current =new Date();
            sessionInfoEntity.setCreatetime(current);
            sessionInfoEntity.setSessionKey(wxMaJscode2SessionResult.getSessionKey());
            sessionInfoEntity.setSessionDuration(current);
            sessionInfoEntity.setLoginToken(accessToken);
            sessionInfoEntity.setLoginDuration(current);
            sessionService.put(fcmUser.getId().toString(), sessionInfoEntity);
            this.logger.info(accessToken);


            result.setMsg(accessToken);
            result.setData(fcmUser);
            return result;
        } catch (WxErrorException e) {
            this.logger.error(e.getMessage(), e);
            result = ResponseResult.error();
            result.setMsg(e.toString());
            return result;
        }
    }

    /**
     * 获取用户信息接口
     *
     * @param fcmUser
     * @param encryptedData
     * @param iv
     * @return
     */
    @PostMapping(value = "/info")
    public ResponseResult info(@LoginUser FcmUser fcmUser,
                               @RequestParam(value = "encryptedData") String encryptedData,
                               @RequestParam(value = "iv") String iv) {
        ResponseResult result = ResponseResult.success();


        SessionInfoEntity sessionInfoEntity = sessionService.get(fcmUser.getId().toString());

        //通过微信接口获取用户数据
        WxMaUserInfo wxMaUserInfo = wxMaService.getUserService().getUserInfo(sessionInfoEntity.getSessionKey(), encryptedData, iv);

        fcmUser = userService.userInfo(fcmUser, wxMaUserInfo);

        result.setData(fcmUser);
        return result;
    }


    /**
     * 获取用户绑定手机号信息
     *
     * @param fcmUser
     * @param encryptedData
     * @param iv
     * @return
     */
    @PostMapping(value = "/phone")
    public ResponseResult phone(@LoginUser FcmUser fcmUser,
                                @RequestParam(value = "encryptedData") String encryptedData,
                                @RequestParam(value = "iv") String iv) {
        ResponseResult result = ResponseResult.success();

        //获取redis服务器的session，通过微信接口获取用户数据
        SessionInfoEntity sessionInfoEntity = sessionService.get(fcmUser.getId().toString());

        WxMaPhoneNumberInfo wxMaPhoneNumberInfo = wxMaService.getUserService().getPhoneNoInfo(sessionInfoEntity.getSessionKey(), encryptedData, iv);

        fcmUser = userService.userPhone(fcmUser, wxMaPhoneNumberInfo);

        result.setData(fcmUser);
        return result;
    }


    /**
     * 获取用户消费明细
     *
     * @param fcmUser
     * @param state
     * @param page
     * @return
     */
    @PostMapping(value = "/queryUserSpend")
    public ResponseResult queryUserSpend(@LoginUser FcmUser fcmUser,
                                         @RequestParam(value = "state", defaultValue = "-1", required = false) long state,
                                         @RequestParam(value = "page", defaultValue = "0", required = false) int page) {
        ResponseResult result = ResponseResult.success();

        List<FcmUserConsumption> list = userService.queryUserSpend(fcmUser.getId(), state, page);
        if (list == null) {
            result = ResponseResult.error();
            result.setMsg("无消费明细");
        }
        result.setData(list);
        return result;
    }

    /**
     * 查看积分明细
     *
     * @param fcmUser
     * @param state
     * @param page
     * @return
     */
    @PostMapping(value = "/userFractionDetail")
    public ResponseResult userFractionDetail(@LoginUser FcmUser fcmUser,
                                             @RequestParam(value = "state", defaultValue = "-1", required = false) long state,
                                             @RequestParam(value = "page", defaultValue = "0", required = false) int page) {
        ResponseResult result = ResponseResult.success();
        List<FcmUserFraction> list = userService.userFractionDetail(fcmUser.getId(), state, page);
        if (list == null) {
            result = ResponseResult.error();
            result.setMsg("无积分明细");
        }
        result.setData(list);
        return result;
    }

    /**
     * 用户扫码获取订单信息
     *
     * @param fcmUser
     * @param orderNumber
     * @return
     */
    @RequestMapping(value = "/userScanQrcoderGetOrderInfo")
    public ResponseResult userScanQrcoderGetOrderInfo(@LoginUser FcmUser fcmUser,
                                                      @RequestParam(value = "orderNumber") String orderNumber) {
        ResponseResult result = ResponseResult.success();
        FcmUserConsumption fcmUserConsumption = payService.userScanQrcoderGetOrderInfo(orderNumber);
        if (fcmUserConsumption == null) {
            result = ResponseResult.error();
            result.setMsg("订单不存在！");
            return result;
        }
        result.setData(fcmUserConsumption);
        return result;
    }


    /**
     * 用户扫码支付
     *
     * @param fcmUser
     * @param orderNumber
     * @return
     */
    @RequestMapping(value = "/userScanQrcoderPay")
    public ResponseResult userScanQrcoderPay(@LoginUser FcmUser fcmUser,
                                             @RequestParam(value = "orderNumber") String orderNumber) {
        ResponseResult result = ResponseResult.success();
        try {
            boolean isPay = payService.userScanQrcoderPay(fcmUser, orderNumber);
            if (isPay) {
                result.setMsg("支付成功");
            } else {
                result = ResponseResult.error();
                result.setMsg("余额不足");
                return result;
            }
        } catch (Exception e) {
            this.logger.error(e.getMessage());
            result = ResponseResult.error();
            result.setMsg("支付失败");
            return result;
        }
        return result;
    }


    /**
     * 查看商家
     *
     * @param page
     * @param search
     * @return
     */
    @PostMapping(value = "/queryStore")
    public ResponseResult queryStore(
            @RequestParam(value = "page", defaultValue = "0", required = false) int page,
            @RequestParam(value = "search", required = false) String search) {
        ResponseResult result = ResponseResult.success();
        List<FcmStoreVO> list = storeService.getStoreList(page, search);
        if (list == null) {
            result = ResponseResult.error();
            result.setMsg("附近暂时无商家入驻");
        }
        result.setData(list);
        return result;
    }


    /**
     * 获取商店信息
     * @param storeId
     * @return
     */
    @PostMapping(value = "/userGetStoreInfo")
    public ResponseResult userGetStoreInfo(@RequestParam(value = "storeId") Long storeId){
        ResponseResult result=ResponseResult.success();
        FcmStoreVO fcmStoreVO=storeService.userGetStoreInfo(storeId);
        result.setData(fcmStoreVO);
        return result;
    }

    /**
     * 用户
     * 充值明细
     * @return
     */
    @PostMapping(value = "/getRechargesList")
    public ResponseResult getRechargesList(@LoginUser FcmUser fcmUser,
                                           @RequestParam(value = "page" ,defaultValue = "0",required = false) int page) {
        ResponseResult result = ResponseResult.success();
        List<FcmUserRecharges> list=payService.getRechargesList(fcmUser.getId(),page);
        result.setData(list);
        return result;
    }

}
